/*
 * Date：10/23/18 10:15 PM
 * Author: guomw
 *
 */

package org.elanfox.intellicommunity.biz.service.core.resident.impl;

import org.elanfox.intellicommunity.biz.dto.condition.LocatorStructureCondition;
import org.elanfox.intellicommunity.biz.entity.auth.SystemManager;
import org.elanfox.intellicommunity.biz.entity.equipment.LocatorPO;
import org.elanfox.intellicommunity.biz.entity.equipment.LocatorPO_;
import org.elanfox.intellicommunity.biz.entity.resident.LocatorStructureRelPO;
import org.elanfox.intellicommunity.biz.entity.resident.LocatorStructureRelPO_;
import org.elanfox.intellicommunity.biz.entity.resident.StructurePO;
import org.elanfox.intellicommunity.biz.repository.resident.LocatorStructureRepository;
import org.elanfox.intellicommunity.biz.service.core.equipment.LocatorService;
import org.elanfox.intellicommunity.biz.service.core.resident.LocatorStructureService;
import org.elanfox.intellicommunity.biz.service.core.resident.StructureService;
import org.elanfox.intellicommunity.data.base.base.AbstractSearchableCrudService;
import org.elanfox.intellicommunity.data.base.base.SpecificationAndSort;
import org.elanfox.intellicommunity.data.base.dto.BaseSaveDTO;
import org.elanfox.intellicommunity.data.base.dto.BaseSearchDTO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;

import javax.persistence.criteria.Predicate;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

/**
 * 管家楼层关联service
 *
 * @author loutianxi
 * @date 2019-12-05
 */
@Service
public class LocatorStructureServiceImpl extends AbstractSearchableCrudService<LocatorStructureRelPO, Integer> implements LocatorStructureService {

    @Autowired
    private LocatorStructureRepository repository;
    @Autowired
    private LocatorService locatorService;
    @Autowired
    private StructureService structureService;

    protected LocatorStructureServiceImpl(LocatorStructureRepository repository) {
        super(repository);
    }

    @Override
    protected SpecificationAndSort<LocatorStructureRelPO> specificationAndSort(BaseSearchDTO condition) {
        LocatorStructureCondition locatorStructureCondition = (LocatorStructureCondition) condition;
        Specification<LocatorStructureRelPO> specification = (root, query, cb) -> {
            List<Predicate> predicates = new ArrayList<>();
            if (locatorStructureCondition.getStructureId() != null) {
                predicates.add(cb.equal(root.get(LocatorStructureRelPO_.structureId), locatorStructureCondition.getStructureId()));
            }
            if (locatorStructureCondition.getNo() != null) {
                predicates.add(cb.equal(root.get(LocatorStructureRelPO_.locatorPO).get(LocatorPO_.no), locatorStructureCondition.getNo()));
            }
            return cb.and(predicates.toArray(new Predicate[predicates.size()]));
        };
        Sort sort = new Sort(Sort.Direction.DESC, "createTime");
        return new SpecificationAndSort<>(specification, sort);
    }


    @Override
    public LocatorStructureRelPO save(BaseSaveDTO saveDTO) {
        LocatorStructureRelPO locatorStructureRelSaveDto = (LocatorStructureRelPO) saveDTO;
        LocatorStructureRelPO locatorStructureRelPO = findById(locatorStructureRelSaveDto.getRelId());
        if (locatorStructureRelPO == null) {
            locatorStructureRelPO = new LocatorStructureRelPO();
        }
        locatorStructureRelPO.setStructureId(locatorStructureRelSaveDto.getStructureId());
        LocatorPO locatorPO = new LocatorPO();
        locatorPO.setLocatorId(locatorStructureRelSaveDto.getRelId());
        locatorStructureRelPO.setLocatorPO(locatorPO);
        return repository.save(locatorStructureRelPO);
    }

    @Override
    public void deleteById(Integer relId) {
        repository.deleteById(relId);
    }

    @Override
    public void save(Integer strId, Long no) {
        LocatorPO locatorPO = locatorService.findByNo(no);
        if (locatorPO == null) {
            throw new IllegalStateException("设备编号不存在");
        }
        LocatorStructureRelPO po = repository.findByStructureIdAndLocatorPO_No(strId, no);
        if (po != null) {
            throw new IllegalStateException("该设备已被添加为附近设备");
        }
        LocatorStructureRelPO locatorStructureRelPO = new LocatorStructureRelPO();
        locatorStructureRelPO.setLocatorPO(locatorPO);
        locatorStructureRelPO.setStructureId(strId);

        SystemManager manager = (SystemManager) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        LocalDateTime now = LocalDateTime.now();
        locatorStructureRelPO.setCreator(manager.getUsername());
        locatorStructureRelPO.setUpdateTime(now);
        locatorStructureRelPO.setCreateTime(now);
        repository.save(locatorStructureRelPO);
    }

    @Override
    public List<LocatorStructureRelPO> findNearbyLocator(Integer strId) {
        StructurePO structurePO = structureService.findById(strId);
        List<LocatorStructureRelPO> list = repository.findByStructureId(structurePO.getPStructureId());
        return list;
    }
}
